package fr.hoteia.appengine.archetype.server.web.controllers;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.MessageSource;
import org.springframework.ui.ModelMap;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
import org.springframework.web.servlet.view.RedirectView;

import fr.hoteia.appengine.archetype.client.Constants;
import fr.hoteia.appengine.archetype.server.service.PortalManager;
import fr.hoteia.appengine.archetype.server.service.UrlManager;
import fr.hoteia.appengine.archetype.server.web.util.ServerUtil;
import fr.hoteia.appengine.archetype.server.web.util.impl.RequestUtilImpl;

/**
 * abstract controller suitable for extension when you'd like to include the
 * currentUser and the ie7 flag.
 * 
 * <p>
 * <a href="AbstractHoteiaController.java.html"><i>View Source</i></a>
 * </p>
 * 
 * @author Denis GOSSET <a href="http://www.hoteia.com"><i>Hoteia.com</i></a>
 * 
 */
public abstract class AbstractHoteiaController extends AbstractController {

	private static final Logger logger = Logger.getLogger(AbstractHoteiaController.class.getName());

	private static ApplicationContext ctx = null;
	
	private PortalManager portalManager;
	private UrlManager urlManager;

	private RequestUtilImpl requestUtil;

	private MessageSource messageSource;

	@Override
	protected ModelAndView handleRequestInternal(final HttpServletRequest request, final HttpServletResponse response) throws Exception {
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.addAllObjects(getDefaultModel(request));
		return modelAndView;
	}

	protected ModelAndView handleRequestInternal(final HttpServletRequest request, final HttpServletResponse response, 
												 ModelAndView modelAndView) throws Exception {
		getRequestUtil().handleRequestLanguage(request, response);

		if (modelAndView == null) {
			modelAndView = new ModelAndView();
			modelAndView.addAllObjects(getDefaultModel(request));
		}
		return modelAndView;
	}

	protected ModelAndView getModelAndView(final HttpServletRequest request, String view, final String redirectView) {

		ModelAndView modelAndView = new ModelAndView();
		String action = getAction(request);
		if(StringUtils.isNotEmpty(action)){
			view = view + "-" + action; // like user-edit, user-save etc
		}
		if (view != null) {
			modelAndView = new ModelAndView(view);
		}

		if (redirectView != null) {
			modelAndView = new ModelAndView(new RedirectView(redirectView));
		}

		return modelAndView;
	}

	protected Map<String, Object> getDefaultModel(final HttpServletRequest request) {
		return getDefaultModel(request, getPortalManager(), getServletContext(), getContext());
	}

	/**
	 * Convenience method to bind objects in Actions
	 * 
	 * @param name
	 * @return
	 */
	public ApplicationContext getContext() {
		if (ctx == null) {
			ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
		}
		return ctx;
	}

	/**
	 * 
	 * @param req
	 * @param userService
	 * @return
	 */
	public Map<String, Object> getDefaultModel(final HttpServletRequest request, final PortalManager portalManager,
											   final ServletContext servletContext, final ApplicationContext context) {

		final Locale locale = getRequestUtil().getCurrentLocale(request);
		
		Map<String, Object> model = new HashMap<String, Object>();

		if (request != null) {
			// IE < 7 check. used in common.ftl PNGImage
			String userAgent = request.getHeader("User-Agent");
			if (userAgent != null && userAgent.contains("MSIE") && !userAgent.contains("MSIE 7")) {
				model.put("iePre7", true);
			}
		}

		model.put("isLocalHostMode", ServerUtil.isLocalHostMode(request));

		try {
			
			model.put("language_en_label", getMessageSource().getMessage("languages." + "EN", null, locale));
			model.put("language_en_url", getUrlManager().getChangeLanguageUrl(request, "en"));

			model.put("language_fr_label", getMessageSource().getMessage("languages." + "FR", null, locale));
			model.put("language_fr_url", getUrlManager().getChangeLanguageUrl(request, "fr"));

		} catch (Exception e) {
			logger.log(Level.SEVERE, e.getMessage());
		}

		return model;
	}

	public ModelMap getModelMap(final HttpServletRequest request, final PortalManager portalManager,
								final ServletContext servletContext, final ApplicationContext context) {
		ModelMap rtn = new ModelMap();
		rtn.addAllAttributes(getDefaultModel(request, portalManager, servletContext, context));
		return rtn;
	}

	public void updateModelMapWithDefaults(final ModelMap map, final HttpServletRequest request, final PortalManager portalManager,
										   final ServletContext servletContext, final ApplicationContext context) {
		map.addAllAttributes(getDefaultModel(request, portalManager, servletContext, context));
	}

	public void resetCache() {
//		getPortalManager()().resetCache();
	}
	
	protected String getAction(final HttpServletRequest request) {
		String action = (String) request.getParameter(Constants.PARAM_ACTION);
		return action;
	}
	
	public PortalManager getPortalManager() {
		return portalManager;
	}

	public void setPortalManager(PortalManager portalManager) {
		this.portalManager = portalManager;
	}

	public UrlManager getUrlManager() {
		return urlManager;
	}

	public void setUrlManager(UrlManager urlManager) {
		this.urlManager = urlManager;
	}
	
	public RequestUtilImpl getRequestUtil() {
		return requestUtil;
	}

	public void setRequestUtil(RequestUtilImpl requestUtil) {
		this.requestUtil = requestUtil;
	}
	
	public MessageSource getMessageSource() {
		return messageSource;
	}

	public void setMessageSource(MessageSource messageSource) {
		this.messageSource = messageSource;
	}
	
}
